package com.yygo.webapp.controller.material;

import com.yygo.Constants;
import com.yygo.model.*;
import com.yygo.model.enums.MaterialStatus;
import com.yygo.model.enums.Phase;
import com.yygo.model.enums.RequestStatus;
import com.yygo.service.LoanProductManager;
import com.yygo.service.LoanRequestManager;
import com.yygo.service.MaterialAuditManager;
import com.yygo.service.UserManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import java.security.Principal;
import java.util.Date;
import java.util.List;

/**
 * Created by tiansha on 2015/10/31.
 */
@Controller
@RequestMapping("/receiveMaterialsForm")
public class ReceiveMaterialsFormController extends BaseMaterialController {

    @Autowired
    private MaterialAuditManager materialAuditManager;

    @Autowired
    private LoanProductManager loanProductManager;

    @Autowired
    private LoanRequestManager loanRequestManager;

    @Autowired
    private UserManager userManager;

    @RequestMapping(method = RequestMethod.GET)
    public String batchReceive(@RequestParam(required = true, value = "maId") Long maId,
                              @RequestParam(required = false, value = "selectedIds") Long[] selectedIds,
                              @RequestParam(required = false, value = "selectedMaterials") String[] selectedMaterials,
                              Principal principal) {
        User loginUser = userManager.getUserByUsername(principal.getName());
        MaterialAudit materialAudit = materialAuditManager.get(maId);
        LoanRequest loanRequest = loanRequestManager.loadWholeLoanRequest(materialAudit.getLoanRequest().getId());

        if (!loginUser.hasRole(Constants.Material_Receive_ROLE)) {
            throw new AccessDeniedException("You have no right to send attachments");
        }

        if(selectedIds!=null) {
            for (Long id : selectedIds) {
                for (Material material : materialAudit.getMaterialList()) {
                    if (material.getId().equals(id)) {
                        material.setReceived(true);
                        material.setReceiveOperator(principal.getName());
                        material.setReceiveDate(new Date());
                    }
                }
            }
        }
        if(selectedMaterials!=null) {
            for (String name : selectedMaterials) {
                Material material = getMaterial(materialAudit, name);
                if (material == null) {
                    material = new Material();
                    material.setName(name);
                    material.setMaterialAudit(materialAudit);
                    materialAudit.getMaterialList().add(material);
                }
                material.setSent(true);
                material.setReceived(true);
                //material.setShipNumber(shipNumber);
                material.setSendDate(new Date());
            }
        }

        // check if loan material complete
        boolean loanComplete = true;
        LoanProduct loanProduct = loanProductManager.loadLoanProduct(materialAudit.getLoanRequest().getLoanProduct().getId());
        //List<String> loanMeterialNames = loanProduct.getLoanMaterialNames();
        List<Material> completeMaterials = buildCompleteMaterials(materialAudit);
        if (verifyCoLoanMaterial(loanRequest, materialAudit.getMaterialList())) {
            for (Material rawMaterial : completeMaterials) {
                if (rawMaterial.isLoanRequest()) {
                    boolean received = false;
                    for (Material material : materialAudit.getMaterialList()) {
                        if (material.getName().equals(rawMaterial.getName())) {
                            if (material.isReceived() && validSpecialMaterial(loanRequest, material.getName())) {
                                received = true;
                            }
                            break;
                        }
                    }
                    if (!received) {
                        loanComplete = false;
                        break;
                    }
                }
            }
        } else {
            loanComplete = false;
        }

        List<Material> materials = materialAudit.getMaterialList();
        mergeMaterials(materials, completeMaterials);

        boolean allSent = true;
        for (Material material : completeMaterials) {
            if (validSpecialMaterial(loanRequest, material.getName()) && !material.isSent()) {
                allSent = false;
            }
        }
        materialAudit.setAllSent(allSent);

        boolean allReceived = true;
        for (Material material : completeMaterials) {
            if (!material.isReceived()) {
                allReceived = false;
            }
        }
        materialAudit.setLoanComplete(loanComplete);
        materialAudit.setAllReceived(allReceived);
        materialAudit.setReceiver(loginUser);
        /*
        if (loanComplete && materialAudit.getLoanRequest().getStatus().equals(RequestStatus.loan_audit)) { // go to next flow
            materialAudit.setMaterialStatus(MaterialStatus.Auditing);
        }
        */
        materialAuditManager.save(materialAudit);

        return "redirect:/receiveMaterials?maId=" + materialAudit.getId();
    }

    /**
     * 如果是共贷，必须要有同意共同还款承诺书
     * @param loanRequest
     * @param materials
     * @return
     */
    private boolean verifyCoLoanMaterial(LoanRequest loanRequest, List<Material> materials) {
        if (loanRequest.isGuaranted() || loanRequest.isCoLoaned()) {
            for (Material material : materials) {
                if (material.isReceived() && material.getName().equals("M6")) {
                    return true;
                }
            }
        } else {
            return true;
        }

        return false;
    }

    private boolean validSpecialMaterial(LoanRequest loanRequest, String mName) {
        if (mName.equals("M35") || mName.equals("M36") || mName.equals("M37")) {
            if (!hasAttachment(loanRequest.getAttachmentList(), mName)) {
                return false;
            }
        }
        return true;
    }

    private boolean hasAttachment(List<Attachment> attachments, String mName) {
        for (Attachment attachment : attachments) {
            if (attachment.getName().equals(mName)) {
                return true;
            }
        }
        return false;
    }
}
